package com.wanger.swa.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanger.swa.dto.templateDynamicField.view.TemplateMaxSortValueView;
import com.wanger.swc.exception.BusEx;
import com.wanger.swc.util.mybatisplus.MyWrapper;
import com.wanger.swc.util.validation.MyVerifyUtil;
import com.wanger.swa.convert.TemplateDynamicFieldConvert;
import com.wanger.swa.dto.templateDynamicField.query.TemplateDynamicFieldQuery;
import com.wanger.swa.dto.templateDynamicField.req.TemplateDynamicFieldAddReq;
import com.wanger.swa.dto.templateDynamicField.req.TemplateDynamicFieldUpdateReq;
import com.wanger.swa.dto.templateDynamicField.resp.TemplateDynamicFieldResp;
import com.wanger.swa.domain.po.TemplateDynamicFieldPO;
import com.wanger.swa.domain.mapper.TemplateDynamicFieldMapper;
import com.wanger.swa.service.ise.TemplateDynamicFieldService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: wanger
 * @Date: 2024/9/15 12:52
 * @Description: 模板动态字段
 */
@Service
@RequiredArgsConstructor
public class TemplateDynamicFieldServiceImpl extends ServiceImpl<TemplateDynamicFieldMapper, TemplateDynamicFieldPO> implements TemplateDynamicFieldService {

    private final TemplateDynamicFieldConvert templateDynamicFieldConvert;

    @Override
    public List<TemplateDynamicFieldResp> getListByTemplateId(String templateId) {
        if (StrUtil.isBlank(templateId)) return Collections.emptyList();
        return getListByTemplateIds(CollUtil.newHashSet(templateId)).getOrDefault(templateId, new ArrayList<>());
    }

    @Override
    public Map<String, List<TemplateDynamicFieldResp>> getListByTemplateIds(Set<String> templateIds) {
        if (CollUtil.isEmpty(templateIds)) return Collections.emptyMap();
        return templateDynamicFieldConvert.toListDTO(
                        this.list(MyWrapper.create(TemplateDynamicFieldPO.class)
                                .in(TemplateDynamicFieldPO::getTemplateId, templateIds)
                                .orderByAsc(TemplateDynamicFieldPO::getSortValue)))
                .stream()
                .collect(Collectors.groupingBy(TemplateDynamicFieldResp::getTemplateId));
    }

    @Override
    @Transactional
    public void addTemplateDynamicFieldList(List<TemplateDynamicFieldAddReq> dtoList) {
        if (CollUtil.isEmpty(dtoList)) return;
        List<TemplateDynamicFieldPO> list = dtoList.stream().map(templateDynamicFieldConvert::toSaveEntity).collect(Collectors.toList());
        if (list.stream().map(TemplateDynamicFieldPO::getName).collect(Collectors.toSet()).size() != list.size()) {
            BusEx.throwEx("占位符名称不能重复！");
        }
        if (list.stream().map(TemplateDynamicFieldPO::getPlaceholder).collect(Collectors.toSet()).size() != list.size()) {
            BusEx.throwEx("占位符不能重复！");
        }
        Map<String, Integer> maxSortValueMap = getTemplateIdMaxSortValueMap();
        for (TemplateDynamicFieldPO po : list) {
            po.setSortValue(getMaxSortValueByTemplateId(maxSortValueMap, po.getTemplateId()));
        }
        this.saveBatch(list);
    }

    @Override
    public TemplateDynamicFieldResp addTemplateDynamicField(TemplateDynamicFieldAddReq addDTO) {
        TemplateDynamicFieldPO templateDynamicField = templateDynamicFieldConvert.toSaveEntity(addDTO);
        templateDynamicField.setSortValue(1);
        this.save(templateDynamicField);
        return templateDynamicFieldConvert.toDetailsDTO(templateDynamicField);
    }

    @Override
    public TemplateDynamicFieldResp updateTemplateDynamicField(TemplateDynamicFieldUpdateReq updateDTO) {
        TemplateDynamicFieldPO templateDynamicField = templateDynamicFieldConvert.toUpdateEntity(updateDTO);
        this.updateById(templateDynamicField);
        templateDynamicField.setUpdateTime(null);
        return templateDynamicFieldConvert.toDetailsDTO(templateDynamicField);
    }

    @Override
    public TemplateDynamicFieldResp getOneTemplateDynamicField(String id) {
        TemplateDynamicFieldPO templateDynamicField = this.getById(id);
        return templateDynamicFieldConvert.toDetailsDTO(templateDynamicField);
    }

    @Override
    public IPage<TemplateDynamicFieldResp> pageTemplateDynamicField(TemplateDynamicFieldQuery query) {
        IPage<TemplateDynamicFieldPO> page = page(
                new Page<>(query.getCurrent(), query.getSize()),
                MyWrapper.create(TemplateDynamicFieldPO.class)
                        .eq(query::getTemplateId)
                        .orderByDesc(TemplateDynamicFieldPO::getSortValue));
        return templateDynamicFieldConvert.toPageDTO(page);
    }

    @Override
    public List<TemplateDynamicFieldResp> listTemplateDynamicField(TemplateDynamicFieldQuery query) {
        return this.pageTemplateDynamicField(query).getRecords();
    }

    @Override
    public void deleteTemplateDynamicField(String id) {
        this.removeById(id);
    }

    @Override
    public void removeByTemplateId(String templateId) {
        MyVerifyUtil.nullVerify(templateId, "模板id不能为空！");
        this.remove(MyWrapper.create(TemplateDynamicFieldPO.class)
                .eq(TemplateDynamicFieldPO::getTemplateId, templateId)
        );
    }

    @Override
    public void removeByTemplateIds(Set<String> templateIds) {
        if (CollUtil.isEmpty(templateIds)) templateIds = new HashSet<>();
        templateIds.add(IdUtil.fastSimpleUUID());
        this.remove(MyWrapper.create(TemplateDynamicFieldPO.class)
                .in(TemplateDynamicFieldPO::getTemplateId, templateIds));
    }

    @Override
    public Map<String, Integer> getTemplateIdMaxSortValueMap() {
        return this.baseMapper.getTemplateIdMaxSortValueMap()
                .stream()
                .collect(Collectors.toMap(TemplateMaxSortValueView::getTemplateId, TemplateMaxSortValueView::getCount, (v1, v2) -> v2));
    }

    /**
     * 从map中获取值，将值加一后更新到map并返回
     *
     * @param map        Map<模板id, 最大排序值>
     * @param templateId 模板id
     * @return 最大排序值+1
     */
    @Override
    public Integer getMaxSortValueByTemplateId(Map<String, Integer> map, String templateId) {
        if (CollUtil.isEmpty(map) || StrUtil.isBlank(templateId)) return 1;
        int max = map.getOrDefault(templateId, 0) + 1;
        map.put(templateId, max);
        return max;
    }
}
